<?php
/**
 * Application level Controller
 *
 * This file is application-wide controller file. You can put all
 * application-wide controller-related methods here.
 *
 * PHP 5
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Controller
 * @since         CakePHP(tm) v 0.2.9
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */

App::uses('Controller', 'Controller');

/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @package       app.Controller
 * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
 */
class AppController extends Controller {
    
    public $uses = array("Organisation", 'AuthApp');
    
    public function beforeFilter() {
        parent::beforeFilter();

        // check app is providing authentication information
        if( !$this->isAppAuthenticated() ) {
            echo $this->_response(array('status' => 'restricted', 'message' => 'Application Not Authenticated'));
            exit;
        }
    }
    
    private function isAppAuthenticated() {
        
        // add simple bypass protocol for apps that need to get into this webservice without authentication
        if( isset($_GET['no_auth']) /*&& $_GET['no_auth'] == base64_decode('webservice')*/ ) {
            return true;
        }
        
        // else check for app authentication session
        if( $this->Session->check('appAuth') && $this->Session->read('appAuth') == $_SERVER['REMOTE_ADDR'] ) {
            return true;
        }
        
        // if not authenticated, try authentication process
        if( isset($this->request->data['APP_KEY']) ) {
            $app_id = $this->request->data['APP_ID'];
            $app_key = $this->request->data['APP_KEY'];
            
            if( $this->AuthApp->authenticate($app_id, $app_key) ) {
                $this->Session->write('appAuth', $_SERVER['REMOTE_ADDR']);
                return true;
            }
        }
        
        // return false if none of the above is provided
        return false; 
    }
    
    public function changeDBConnection($host, $database) {
        if( $host == '' || $database == '') {
            return false;
        }
        
        $config = array(
            'host' => $host,
            'database' => $database
        );

        $db = & ConnectionManager::getDataSource('default');

        $db->disconnect();

        $db->setConfig($config);

        $db->connect();
        
        return true; 
    }
    
    /**
     * Function for return json from given array.
     * @author Anoop  P.R.
     * @param  array  $json_data
     * @return json           
     */
    protected function _response($json_data = array()) {
        return new CakeResponse(array('type' => 'json', 'body' => json_encode($json_data)));
    }
    
    /**
     * Function for validating the input parameters.
     * @author Anoop  P.R.
     * @param  array  $rules 
     * @param  array  $data  
     */
    protected function _validateParams($rules = array(), $data = array()) {
        $error = false;
        $errorMsg = array();
        
        if( empty($data) ) {
            if( $this->request->is("post") ) {
                $data = $this->request->data;
            }
            
            else {
                $data = $this->request->query;
            }
        }
        
        foreach ($rules as $rule => $fields) {

            if(trim($rule) == 'required') {
                $response = $this->__checkRequired($fields, $data);
                if($response['status'] == 'failed') {
                    $error = true;
                    $errorMsg = array_merge($errorMsg, $response['msg']);
                }
            }

            if(trim($rule) == 'numeric') {
                $response = $this->__checkNumeric($fields, $data);
                if($response['status'] == 'failed') {
                    $error = true;
                    $errorMsg = array_merge($errorMsg, $response['msg']);
                }
            }
        }   
        if (!$error) {
            return "NO_ERROR";
        } else {
            $response = array(
                'status' => 'failed',
                "msg" => "Invalid parameter Passed.",
                "details" => $errorMsg
            );
            return $this->_response($response);
        }
    }
    
    /**
     * [__checkRequired description]
     * @author Anoop P R
     * @param  string $fields 
     * @param  array  $data   
     * @return boolean
     */
    private function __checkRequired($fields='', $data = array()) {
        if(empty($fields)) {
            return array(
                    'status' => 'failed',
                    'msg' => array('Required fields list not found.')
                );
        }
        $output = array();
        $params = explode(',', $fields);
        foreach($params as $field) {
            if(!isset($data[trim($field)]) || $data[trim($field)] == "") {
                $output[] = 'Input parameter \''. trim($field) .'\' is missing';
            }
        }
        if(empty($output)) {
            return array(
                    'status' => 'success',
                    'msg' => 'NO_ERROR'
                );
        } else {
            return array(
                    'status' => 'failed',
                    'msg' => $output
                );
        }
    }

    /**
     * [__checkNumeric description]
     * @author Anoop P R
     * @param  string $fields 
     * @param  array  $data   
     * @return boolean         
     */
    private function __checkNumeric($fields='', $data = array()) {
        if(empty($fields)) {
            return array(
                    'status' => 'failed',
                    'msg' => array('Required fields list not found.')
                );
        }
        $output = array();
        $params = explode(',', $fields);
        foreach ($params as $field) {
            if(!empty($data[trim($field)]) && !is_numeric($data[trim($field)])) {
                $output[] = 'Parameter \''. trim($field) .'\' should be numeric.';
            }
        }
        if(empty($output)) {
            return array(
                    'status' => 'success',
                    'msg' => 'NO_ERROR'
                );
        } else {
            return array(
                    'status' => 'failed',
                    'msg' => $output
                );
        }
    }
}
